package com.imooc.service.impl;

import com.imooc.dto.OrderDTO;
import com.imooc.enums.ResultEnum;
import com.imooc.exception.SellException;
import com.imooc.service.OrderService;
import com.imooc.service.PayService;
import com.imooc.utils.JsonUtil;
import com.imooc.utils.MathUtil;
import com.lly835.bestpay.enums.BestPayTypeEnum;
import com.lly835.bestpay.model.PayRequest;
import com.lly835.bestpay.model.PayResponse;
import com.lly835.bestpay.model.RefundRequest;
import com.lly835.bestpay.model.RefundResponse;
import com.lly835.bestpay.service.impl.BestPayServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * FileName: PayServiceImpl.java
 * Description: PayServiceImpl
 *
 * @author HuangRI(874668739 @ qq.com)
 * @version 1.0
 * @date 2020/12/28
 */
@Service
@Slf4j
public class PayServiceImpl implements PayService {

    private static final String ORDER_NAME = "微信订餐订单";

    @Autowired
    private BestPayServiceImpl bestPayService;

    @Autowired
    private OrderService orderService;

    @Override
    public PayResponse create(OrderDTO orderDTO) {
        PayRequest payRequest = new PayRequest();
        payRequest.setOrderId(orderDTO.getOrderId());
        payRequest.setOrderAmount(orderDTO.getOrderAmount().doubleValue());
        payRequest.setOpenid(orderDTO.getBuyerOpenid());
        payRequest.setOrderName(ORDER_NAME);
        payRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_H5);
        log.info("【微信支付】发起支付，payRequest={}", JsonUtil.toJson(payRequest));
        PayResponse payResponse = this.bestPayService.pay(payRequest);
        log.info("【微信支付】发起支付，payResponse={}", JsonUtil.toJson(payResponse));
        return payResponse;
    }

    @Override
    public PayResponse notify(String notifyData) {
        // 1、验证签名 -- 由best-sdk支持
        // 2、支付状态判断 -- 由best-sdk支持
        log.info("【微信支付】支付结果异步通知，notifyDat={}", notifyData);
        PayResponse payResponse = this.bestPayService.asyncNotify(notifyData);
        log.info("【微信支付】支付结果异步通知，payResponse={}", JsonUtil.toJson(payResponse));

        String orderId = payResponse.getOrderId();
        OrderDTO orderDTO = this.orderService.findOne(orderId);
        if (null == orderDTO) {
            log.error("【微信支付】支付结果异步通知，订单不存在，orderId={}", orderId);
            throw new SellException(ResultEnum.ORDER_NOT_EXIST);
        }

        // 3、支付金额校验
        // 精度问题：orderDTO.getOrderAmount().compareTo(new BigDecimal(payResponse.getOrderAmount())) != 0
        if (!MathUtil.equals(orderDTO.getOrderAmount().doubleValue(), payResponse.getOrderAmount())) {
            log.error("【微信支付】支付结果异步通知，订单金额不一致，orderId={}，微信通知金额={}，系统金额={}",
                    orderId, payResponse.getOrderAmount(), orderDTO.getOrderAmount().doubleValue());
            throw new SellException(ResultEnum.WXPAY_NOTIFY_MONEY_VERIFY_ERROR);
        }

        // 4、支付人（下单人 == 支付人）：本应用不限制
        this.orderService.paid(orderDTO);
        return payResponse;
    }

    @Override
    public RefundResponse refund(OrderDTO orderDTO) {
        RefundRequest refundRequest = new RefundRequest();
        refundRequest.setOrderAmount(orderDTO.getOrderAmount().doubleValue());
        refundRequest.setOrderId(orderDTO.getOrderId());
        refundRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_H5);
        log.info("【微信退款】request={}", JsonUtil.toJson(refundRequest));
        RefundResponse refundResponse = this.bestPayService.refund(refundRequest);
        log.info("【微信退款】response={}", JsonUtil.toJson(refundResponse));
        return refundResponse;
    }
}
